﻿/*
 * 
 * User: artem
 * Date: 18.05.2011
 * Time: 10:45
 * 
 * 
 */
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;

using CacheObjects;
using Kernel;
using SettingManager;

using OOECode = Kernel.OpenOrganizerException.ErrorCode;
using OOExp = Kernel.OpenOrganizerException;
using System.Diagnostics;

namespace Demon
{
	/// <summary>
	/// Description of Controller.
	/// </summary>
	public sealed class Controller : DataBaseService
	{
        private const string setting_file_path = @"DemonSettings.conf";

        private XMLSettingManager settings = null;
		private Timer load_events_timer;
		private IDBDemon data_base;
		private CacheObjects<int, Event> cache;
        private NotificationWatcher watcher;
		
		private static Controller instance = new Controller();
		
		public static Controller Instance 
		{ get { return instance; } }

        private Controller()
        {
            data_base = DataBase.Instance as IDBDemon;

            try
            { this.PerfomeEventService(DataBase.Instance as IDBService); }
            catch { }

            watcher = new NotificationWatcher();
            cache = new CacheObjects<int, Event>();
            load_events_timer = new Timer(this.LoadEvents);
            LoadEventAndNotification();
            load_events_timer.Change(TimeSpan.FromTicks(0), TimeSpan.FromMinutes(1));
            settings = XMLSettingManager.Load(setting_file_path);
        }

        public IWatcher Watcher
        { get { return (watcher as IWatcher); } }

		private void LoadEvents(object ignored)
		{
            lock (this)
                LoadEventAndNotification();
		}

        private void LoadEventAndNotification()
        {
            cache.Clear();

            var events = data_base.GetEventsForNotifications();

            DateTime current_notification;
            TimeSpan period;
            foreach (var it in events)
            {
                cache.Add(it.ID, it);

                period =
                   new TimeSpan((it.NotificationEnd.Ticks -
                                 it.NotificationStart.Ticks) /
                                     it.NotificationCount);

                current_notification = it.NotificationStart;
                for (int i = 0; i < it.NotificationCount; i++)
                {
                    if (current_notification > DateTime.Now)
                        watcher.AddNotification(it.ID, current_notification);

                    current_notification += period;
                }

                watcher.AddNotification(it.ID, it.Date);
            }
        }

        public dynamic GetEventInfo(int id)
        {
            var it = data_base.GetEvent(id);

            return new
                {
                    Title = it.Title,
                    Description = it.Description,
                    Date = it.Date.ToLongDateString() + it.Date.ToLongTimeString(),
                    Type = it.Type.ToString(),
                    Periodic = it.Periodicity != Event.EventPeriodicity.None
                };
        }

        public void RunClient()
        {
            Process.Start(settings[@"ClientPath"]);
        }
    }
}
